package name.swingeet.rmi;

import java.rmi.AccessException;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import name.swingeet.swingElf.SwingTestImpl;
import name.swingeet.swingElf.SwingTestInterface;



public class RMIRegistryManager
{
	public  static int    DEFAULT_PORT       = 1099;
	public  static String DEFAULT_AGENT_NAME = "Swingeet";

	private static long REGISTRY_CHECK_INTERVAL = 30000;

	private SwingTestImpl attachAgent = new SwingTestImpl();

	private boolean objectExported = false;

	private int    port;
	private String agentName;

	/**************************************************************************
	* 
	**************************************************************************/
	public RMIRegistryManager()
	{
		this(DEFAULT_PORT);
	}

	/**************************************************************************
	* @param port
	**************************************************************************/
	public RMIRegistryManager(int port)
	{
		this(port, DEFAULT_AGENT_NAME);
	}

	/**************************************************************************
	* @param port
	* @param name
	**************************************************************************/
	public RMIRegistryManager(int port, String agentName)
	{
		this.port      = port;
		this.agentName = agentName;

		Thread thread = createRegistryThread();
		thread.setDaemon(true);
		thread.setPriority(Thread.NORM_PRIORITY - 1);
	
		thread.start();
		try {
			thread.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**************************************************************************
	* 
	* @return registry manager thread
	**************************************************************************/
	private Thread createRegistryThread()
	{
		return new Thread()
		{
			public void run()
			{
				try{
//					while(true)
					{
						registerToRegistry();
						Thread.sleep(REGISTRY_CHECK_INTERVAL);
					}
				}catch(InterruptedException ie)
				{
					// ignore, we are exiting...
				}finally
				{
//System.err.println("UNBOUND AGENT !!!!!!!!!!!!!!!!!!!!!!!!!!");
//					try{
//						Registry registry = LocateRegistry.getRegistry();
//						registry.unbind(RMIRegistryManager.this.agentName);
//					}catch(Exception re)
//					{
//						// ignore
//					}
				}
			}
		};
	}

	/**************************************************************************
	* 
	**************************************************************************/
	private void registerToRegistry()
	{
		Registry registry = null;

		try{
			registry = LocateRegistry.createRegistry(port);
		}catch(RemoteException re)
		{
			re.printStackTrace();
			System.exit(1);
		}

		try{
			SwingTestInterface stub = (SwingTestInterface)UnicastRemoteObject.exportObject(this.attachAgent, 0);
			registry.bind(this.agentName, stub);
			System.out.println(registry.list());
		} catch (AccessException e)
		{
			e.printStackTrace();
		} catch (RemoteException e)
		{
			e.printStackTrace();
		} catch (AlreadyBoundException e)
		{
			e.printStackTrace();
		}
		System.out.println("register successed");
		this.objectExported = true;
	}

	/**************************************************************************
	* 
	* @return the spy agent
	**************************************************************************/
	public SwingTestInterface getAttachAgent()
	{
		return attachAgent;
	}

	/**************************************************************************
	* 
	* @return
	**************************************************************************/
	public int getPort()
	{
		return this.port;
	}

	/**************************************************************************
	* 
	* @return
	**************************************************************************/
	public String getAgentName()
	{
		return this.agentName;
	}
}
